package com.zy.sso.service.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PathVariable;

import com.zy.common.util.CookieUtils;
import com.zy.common.util.JsonUtils;
import com.zy.common.util.TaotaoResult;
import com.zy.mapper.TbUserMapper;
import com.zy.pojo.TbUser;
import com.zy.pojo.TbUserExample;
import com.zy.pojo.TbUserExample.Criteria;
import com.zy.sso.dao.JedisClient;
import com.zy.sso.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	@Autowired
	private TbUserMapper userMapper;
	/*
	 * 缓存
	 */
	@Autowired
	private JedisClient jedisClient;
	/*
	 * 用户session在redis中保存的key
	 */
	@Value("${REDIS_USER_SESSION_KEY}")
	private String REDIS_USER_SESSION_KEY;
	/*
	 * 设置session的过期时间30分钟
	 */
	@Value("${SSO_SESSION_EXPIRE}")
	private int SSO_SESSION_EXPIRE;

	/**
	 * 数据校验 1、2、3分别代表username、phone、email
	 */
	@Override
	public TaotaoResult checkData(String param, Integer type) {
		// 创建条件对象
		TbUserExample tbUserExample = new TbUserExample();
		Criteria criteria = tbUserExample.createCriteria();
		// 对数据进行校验：1、2、3分别代表username、phone、email
		if (1 == type) {
			criteria.andUsernameEqualTo(param);
		} else if (2 == type) {
			criteria.andPhoneEqualTo(param);
		} else {
			criteria.andEmailEqualTo(param);
		}
		// 执行查询
		List<TbUser> list = userMapper.selectByExample(tbUserExample);
		if (list == null || list.size() == 0) {
			// 账户可用 返回 json 200 "ok" true
			return TaotaoResult.ok(true);
		}
		return TaotaoResult.ok(false);
	}

	/**
	 * 创建用户
	 */
	@Override
	public TaotaoResult createUser(TbUser user) {
		try {
			user.setUpdated(new Date());
			user.setCreated(new Date());
			// md5加密
			user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
			userMapper.insert(user);
		}catch (Exception e) {
			// TODO: handle exception
			return new TaotaoResult(400,"注册异常",null);
		}
		//注册成功，js通过状态码判断
		return TaotaoResult.ok();
	}

	/**
	 * 登录实现，并完成存入缓存和Cookie
	 */
	@Override
	public TaotaoResult userLogin(String username, String password, HttpServletRequest request,
			HttpServletResponse response) {
		// 1. 创建查询条件对象
		TbUserExample example = new TbUserExample();
		Criteria criteria = example.createCriteria();
		criteria.andUsernameEqualTo(username);
		List<TbUser> list = userMapper.selectByExample(example);
		// 2. 如果没有此用户名
		if (null == list || list.size() == 0) {
			return TaotaoResult.build(400, "用户名或密码错误");
		}
		// 3. 得到集合中user
		TbUser user = list.get(0);
		// 4. 比对密码
		String md5DigestAsHex = DigestUtils.md5DigestAsHex(password.getBytes());
		if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())) {
			return TaotaoResult.build(400, "用户名或密码错误");
		}
		// 5. 生成随机token标记作键
		String token = UUID.randomUUID().toString();
		// 保存用户之前，把用户对象中的密码清空,因为只需知道用户名存在即可，表示已登录
		user.setPassword(null);
		// 6. 把用户信息写入redis
		jedisClient.set(REDIS_USER_SESSION_KEY + ":" + token, JsonUtils.objectToJson(user));
		// 设置session的过期时间
		jedisClient.expire(REDIS_USER_SESSION_KEY + ":" + token, SSO_SESSION_EXPIRE);
		
		// 7.在Cookie中保存生成的token值，以便于单点登陆访问
		// 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
		CookieUtils.setCookie(request, response, "TT_TOKEN", token);
		// 8. 返回token  200  "ok" token
		return TaotaoResult.ok(token);
	}

	/**
	 * 根据token（标记，用作键）到redis查询用户信息，用于单点登陆，访问不同服务器页面时使用远程调用判断
	 */
	@Override
	public TaotaoResult getUserByToken(String token) {
		// 根据token从redis中查询用户信息
		String json = jedisClient.get(REDIS_USER_SESSION_KEY + ":" + token);
		// 判断是否为空
		if (StringUtils.isBlank(json)) {
			return TaotaoResult.build(400, "此session已经过期，请重新登录");
		}
		// 更新过期时间,重新设定
		jedisClient.expire(REDIS_USER_SESSION_KEY + ":" + token, SSO_SESSION_EXPIRE);
		// 在转成对象
		TbUser jsonToPojo = JsonUtils.jsonToPojo(json, TbUser.class);
		return TaotaoResult.ok(jsonToPojo);
	}

	/**
	 * 安全退出
	 */
	@Override
	public TaotaoResult userLogout(String token) {
		//清楚缓存,不需要清楚Cookie，浏览器关闭后自动清除Cookie
		try {
			jedisClient.del(REDIS_USER_SESSION_KEY+":"+token);
		}catch (Exception e) {
			return new TaotaoResult(400,"清除异常",false);
		}
		return TaotaoResult.ok();
	}
}
